#include "threadPool.h"
int makeWorker(threadPool_t *threadPool)
{
    for (int i = 0; i < threadPool->workerNum; ++i)
    {
        pthread_create(&threadPool->tidArr[i], NULL, threadFunc, threadPool);
    }
    return 0;
}

void *threadFunc(void *arg)
{
    threadPool_t *threadPool = (threadPool_t *)arg;
    char cmd[10] = {0};
    char client_arg[100] = {0};
    char buf[100] = {0};
    char name[30] = {0};
    int file_id = -1;
    char session_id[1024] = {0};

    pthread_mutex_lock(&threadPool->taskQueue.mutex);
    MYSQL *mysql = mysql_init(NULL);
    MYSQL *ret_connect = mysql_real_connect(mysql, "localhost", "root", "743957", "server_db", 0, NULL, 0);
    if (ret_connect == NULL)
    {
        fprintf(stderr, "mysql connect error:%s\n", mysql_error(mysql));
    }
    pthread_mutex_unlock(&threadPool->taskQueue.mutex);
    // 每个线程连接一个数据库

    pthread_mutex_lock(&threadPool->taskQueue.mutex);
    while (threadPool->taskQueue.queueSize == 0 && threadPool->exitflag == 0)
    {
        pthread_cond_wait(&threadPool->taskQueue.cond, &threadPool->taskQueue.mutex);
    }

    if (threadPool->exitflag != 0)
    {
        printf("child is going to exit!\n");
        pthread_mutex_unlock(&threadPool->taskQueue.mutex);
        pthread_exit(NULL);
    }

    int sockfd = threadPool->taskQueue.pFront->netfd; // 第三期存储netfd的位置用于存储sockfd用于子进程和服务端建立连接 todo 检查代码其他位置是否有使用netfd
    int netfd = accept(sockfd, NULL, NULL);
    //strcpy(cmd, threadPool->cmd_argv);
    //strcpy(client_arg, threadPool->cmd_argv);

    printf("child get a task!\n");
    // int netfd = threadPool->taskQueue.pFront->netfd;
    deQueue(&threadPool->taskQueue);
    pthread_mutex_unlock(&threadPool->taskQueue.mutex);

    recv_msg(netfd, name);
    recv_msg(netfd, session_id);
    int ret_tc =  token_check(name,session_id);
    if(ret_tc == -1)
    {
        goto failure_check;
    }
    if (strcmp(cmd, "puts") == 0)
    {
        char path_file[100] = {"file/"};
        char path_user[100] = {0};
        char command_puts[1024] = {0};
        char md5[33] = {0};
        char command_check[100] = {0};
        char ret_message[100] = {0};
        char file_check[100] = {0};
        recv_msg(netfd, file_check);
        if ((strcmp(file_check, "文件不存在!\n")) == 0)
        {
            // continue;
        }
        else
        {
            recv_msg(netfd, md5);
            // 接收md5
            pwd(&file_id, path_user, mysql);
            // printf("path = %s  filename = %s\n",path_user,client_arg);
            strcat(path_user, client_arg);

            sprintf(command_check, "select * from file_tbl where path = '%s' and filename = '%s';", path_user, client_arg);

            mysql_query(mysql, command_check);
            MYSQL_RES *result = mysql_store_result(mysql);
            MYSQL_ROW row = mysql_fetch_row(result);
            if (row)
            { // 如果找到了说明以及有文件了
                strcpy(ret_message, "文件已存在！\n");
                send_msg(netfd, ret_message);
                // continue;
            }
            else
            {
                strcpy(ret_message, "校验成功，正在上传\n");
                send_msg(netfd, ret_message);

                bzero(ret_message, sizeof(ret_message));
                bzero(command_check, sizeof(command_check)); // 清空命令
                sprintf(command_check, "select * from file_tbl where md5 = '%s';", md5);
                mysql_query(mysql, command_check);
                result = mysql_store_result(mysql);
                row = mysql_fetch_row(result);
                if (row)
                {
                    strcpy(ret_message, "上传成功!\n");
                    send_msg(netfd, ret_message);
                }
                else
                {
                    send_msg(netfd, "111");
                    strcat(path_file, md5);
                    getsfile(netfd, path_file);
                }
                sprintf(command_puts, "insert into file_tbl (filename,user_name, pre_id,type,path,is_delete,md5) values ('%s','%s',%d,'file','%s','0','%s');", client_arg, name, file_id, path_user, md5);
                int qret = mysql_query(mysql, command_puts);
                if (qret != 0)
                {
                    printf("%d\n", qret);
                    fprintf(stderr, "SQL statement error : %s\n", mysql_error(mysql));
                }
            }
        }
    }
    else if (strcmp(cmd, "gets") == 0)
    {
        recv_msg(netfd, client_arg);
        // 收到文件名
        char path_gets[100] = {0};
        char path_filename[100] = {0};
        char command_getmd5[100] = {0};
        pwd(&file_id, path_gets, mysql);
        // 得到当前用户目录
        strcat(path_gets, client_arg);
        // 合并当前目录和文件名
        sprintf(command_getmd5, "select md5 from file_tbl where user_name = '%s' and path = '%s';", name, path_gets);
        int qret = mysql_query(mysql, command_getmd5);
        MYSQL_RES *result = mysql_store_result(mysql);
        send(netfd, &qret, sizeof(qret), 0);
        if (qret != 0)
        {
            fprintf(stderr, "SQL statement error : %s\n", mysql_error(mysql));
            // continue;
        }
        else
        {
            MYSQL_ROW row = mysql_fetch_row(result);
            strcat(path_filename, "file/");
            strcat(path_filename, *row);
            printf("%s\n", path_filename);
            transfile(netfd, path_filename);
            // 下载后把文件引用数减一
            bzero(command_getmd5, sizeof(command_getmd5));
            sprintf(command_getmd5, "update file_tbl set is_delete = '1' where md5 = '%s';", *row);
            printf("%s\n", command_getmd5);
            qret = mysql_query(mysql, command_getmd5);
            if (qret != 0)
            {
                fprintf(stderr, "SQL statement error : %s\n", mysql_error(mysql));
                // continue;
            }
        }
    }

failure_check:    close(netfd);

}

int users_login(threadPool_t *threadPool, int netfd, client_info_t *user_tbl)
{
    char cmd[10] = {0};
    char client_arg[100] = {0};
    char buf[100] = {0};
    char name[30] = {0};
    char password[100] = {0};
    int user_id = -1;
    int file_id = -1;
    int password_check; // 登录返回值
    char session_id[256] = {0};

    pthread_mutex_lock(&threadPool->taskQueue.mutex);
    MYSQL *mysql = mysql_init(NULL);
    MYSQL *ret_connect = mysql_real_connect(mysql, "localhost", "root", "743957", "server_db", 0, NULL, 0);
    if (ret_connect == NULL)
    {
        fprintf(stderr, "mysql connect error:%s\n", mysql_error(mysql));
    }
    pthread_mutex_unlock(&threadPool->taskQueue.mutex);

    while (1)
    {
        memset(name, 0, sizeof(name));
        memset(password, 0, sizeof(password));
        recv_msg(netfd, name);
        recv_msg(netfd, password);

        // 判断用户名 和密码是否正确
        int pass_ret = passwd_check(name, password, mysql, &user_id);
        // printf("%d\n",password_check);
        if (pass_ret == -1)
        {
            send_msg(netfd, "密码错误!");
            while (1)
            {
                bzero(password, sizeof(password));
                recv_msg(netfd, password);
                // 等待新密码
                pass_ret = passwd_check(name, password, mysql, &user_id);
                // 判断是否正确
                if (pass_ret == -1)
                {
                    send_msg(netfd, "密码错误");
                    continue;
                }
                break;
            }
        }
        else if (pass_ret == 1)
        {
            send_msg(netfd, "注册成功!");
            char temp[100] = {0};
            strcat(temp, name);
            strcat(temp, "/");

            int mkdir_ret = mkdir_server(name, temp, name, &file_id, mysql);
            if (mkdir_ret == -1)
            {
                sprintf(buf, "make the wrong directory");
            }
            else
            {
                ls(mysql, client_arg, &file_id, buf);
            }
            send_msg(netfd, buf);
        }
        else
        {
            send_msg(netfd, "登录成功!");
            strcpy(user_tbl[netfd].username, name);
            change_id(name, &file_id, -1, mysql);
            user_tbl[netfd].cur_id = file_id;
            break;
        }
    }
}

// 先接收指令若为短指令  若为长指令
int cmd_execute(threadPool_t *threadPool, int netfd, int sockfd, client_info_t *user_tbl)
{
    char cmd[10] = {0};
    char client_arg[100] = {0};
    char buf[100] = {0};
    char name[30] = {0};
    int file_id = -1;
    char session_id[256] = {0};

    memset(name, 0, sizeof(name));
    memset(session_id, 0, sizeof(session_id));
    memset(cmd, 0, sizeof(cmd));
    memset(client_arg, 0, sizeof(client_arg));

    strcpy(name, user_tbl[netfd].username);
    file_id = user_tbl[netfd].cur_id;
    // recv_msg(netfd, name);
    // recv_msg(netfd, session_id);
    recv_msg(netfd, cmd);
    recv_msg(netfd, client_arg);

    if(cmd=="\0"){
        close(netfd);
        return -1;
    }

    send_msg(netfd, name);
    int ret_tg = token_genarate(name,session_id);
    if(ret_tg == -1)
    {
        return -1;
    }
    send_msg(netfd, session_id);
    // 连接数据库
    pthread_mutex_lock(&threadPool->taskQueue.mutex);
    MYSQL *mysql = mysql_init(NULL);
    MYSQL *ret_connect = mysql_real_connect(mysql, "localhost", "root", "743957", "server_db", 0, NULL, 0);
    if (ret_connect == NULL)
    {
        fprintf(stderr, "mysql connect error:%s\n", mysql_error(mysql));
    }
    pthread_mutex_unlock(&threadPool->taskQueue.mutex);

    printf("%s\n", name);
    if (cmd[0] == '\0') // 无命令
    {
        return -1;
    }

    // 由子进程执行长指令
    //if(strcmp(cmd,"quit")==0){
     //   sleep(10);
    //}
    if (strcmp(cmd, "puts") == 0 || strcmp(cmd, "gets") == 0)
    {
        recv_msg(netfd, name);
        recv_msg(netfd, session_id);

        pthread_mutex_lock(&(threadPool->taskQueue).mutex);

        //strcpy(threadPool->cmd, cmd);
        //strcpy(threadPool->cmd_argv, client_arg);

        enQueue(&(threadPool->taskQueue), sockfd,file_id,cmd,client_arg); // 为不修改原函数 ，netfd用来存储sockfd让子线程与服务端子线程进行通信
        printf("main send a new task!\n");
        pthread_cond_broadcast(&(threadPool->taskQueue).cond);
        pthread_mutex_unlock(&(threadPool->taskQueue).mutex);
    }

    else // 执行短指令
    {
        if (strcmp(cmd, "cd") == 0)
        {
            printf("client_arg=%s file_if =%d buf=%s\n", client_arg, file_id, buf);

            int cd_ret = cd(mysql, client_arg, &file_id, buf);
            printf("client_arg=%s file_if =%d buf=%s\n", client_arg, file_id, buf);
            printf("%s\n", buf);
            if (cd_ret == -1)
            {
                sprintf(buf, "cd the wrong directory");
            }
            send_msg(netfd, buf);
        }
        else if (strcmp(cmd, "mkdir") == 0)
        {
            char path_pwd[100] = {0};
            pwd(&file_id, path_pwd, mysql);
            int mkdir_ret = mkdir_server(client_arg, path_pwd, name, &file_id, mysql);
            if (mkdir_ret == -1)
            {
                sprintf(buf, "make the wrong directory");
            }
            else
            {
                ls(mysql, "\0", &file_id, buf);
            }
            send_msg(netfd, buf);
        }
        else if (strcmp(cmd, "ls") == 0)
        {
            int ls_ret = ls(mysql, client_arg, &file_id, buf);
            if (ls_ret == -1)
            {
                sprintf(buf, "ls the wrong directory");
            }
            send_msg(netfd, buf);
        }
        else if (strcmp(cmd, "puts") == 0)
        {

            char path_file[100] = {"file/"};
            char path_user[100] = {0};
            char command_puts[1024] = {0};
            char md5[33] = {0};
            recv_msg(netfd, md5);

            pwd(&file_id, path_user, mysql);
            strcat(path_user, client_arg);

            sprintf(command_puts, "insert into file_tbl (filename,user_id, pre_id,type,path,is_delete,md5) values ('%s','%s',%d,'file','%s','1','%s');", client_arg, name, file_id, client_arg, md5);
            mysql_query(mysql, command_puts);

            strcat(path_file, md5);
            getsfile(netfd, path_file);
        }
        else if (strcmp(cmd, "remove") == 0)
        {
            char path_pwd[100] = {0};
            pwd(&file_id, path_pwd, mysql);
            int ret_remove = remove_server(client_arg, path_pwd, name, mysql);
            if (ret_remove == -1)
            {
                send_msg(netfd, "删除失败!\n");
            }
            else
            {
                send_msg(netfd, "删除成功!\n");
            }
        }
        else if (strcmp(cmd, "rmdir") == 0)
        {
            char path_pwd[100] = {0};
            pwd(&file_id, path_pwd, mysql);
            int ret_rmdir = rmdir_server(client_arg, path_pwd, name, &file_id, mysql);
            if (ret_rmdir == -1)
            {
                sprintf(buf, "删除失败\n");
            }
            else
            {
                sprintf(buf, "删除成功");
            }
            send_msg(netfd, buf);
        }
        else if (strcmp(cmd, "tree") == 0)
        {

            int tree_ret = tree(mysql, &file_id, buf, 0);
            if (tree_ret == -1)
            {
                sprintf(buf, "打开树失败!");
            }
            send_msg(netfd, buf);
        }
        else if (strcmp(cmd, "pwd") == 0)
        {
            char path_pwd[100] = {0};
            pwd(&file_id, path_pwd, mysql);

            strcat(path_pwd, "\n");
            send_msg(netfd, path_pwd);
        }
        printf(" finish a task!\n");
    }
    user_tbl[netfd].cur_id = file_id;
}
